/**
 * 模拟Promise-ajax形式，操作后台的Table数据
 *
 * 现有方法有：
 *  ajax.initTable(table)：初始化 talbe 的数据
 *    注：！！若 table 中没数据，才向 table 中增加数据！！
 *  ajax.setAll(table)：更改整个 table 的数据
 *  ajax.set(id, data)：通过 id，更改 已存在的 一行数据
 *  ajax.getAll()：获取 table 的所有数据
 *  ajax.get(id)：通过 ID 获取指定行的数据
 *  ajax.delete(id)：通过 id 删除 table 中已存在的某行数据
 *  ajax.append(data)：向 table 的末尾添加一行数据
 */
// 模拟 用户名 与 密码
const mockLoginData = {
  username: "admin",
  password: "123456",
};

export const ajax = {
  /**
   * 模拟用户登录接口
   * 注：账号密码必须是： { username: 'admin', password: '123456'}
   * @param {Object} loginData
   * @returns {Promise<{status: string, message: string}>}
   */
  login(loginData) {
    if (loginData?.username !== mockLoginData.username) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject({ status: "error", message: "账号错误；账号必须为: admin" });
        }, 1000);
      });
    }
    if (loginData?.password !== mockLoginData.password) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject({ status: "error", message: "密码错误；密码必须为: 123456" });
        }, 1000);
      });
    }
    return mockPromiseRes({ status: "success", message: "登录成功" });
  },
  /**
   * 初始化 talbe 的数据
   *    注：！！若 table 中没数据，才向 table 中增加数据！！
   * @param {Array} table
   */
  initTable(table) {
    if (!getTable()) {
      setTable(table);
    }
  },
  /**
   * 彻底替换整个 table 的数据
   * @param {Array} table
   *
   * @return {Boolean} {status: 'success'} 为数据初始化成功，
   *  {status: 'error'} 为数据初始化失败
   */
  setAll(table) {
    setTable(table);
    return mockPromiseRes({ status: "success" });
  },

  /**
   * 通过 ID 获取指定数据
   * @param {String} id
   *
   * @return {Promise<Object>} 获取到的「单行」数据
   */
  get(id) {
    const target = getTable().find((d) => d?.id == id);
    return mockPromiseRes(target);
  },

  /**
   * 获取 table 的所有数据
   *
   * @return {Promise<Array>}
   */
  getAll() {
    const table = getTable();
    return mockPromiseRes(table);
  },

  /**
   * 通过 id，更改 已存在的 一行数据
   *   注：data 的 key 必须是和 table 每行的 key 一致
   * @param {String} id
   * @param {Object} data
   *
   * @return {Boolean} {status: 'success'} 为更爱成功，
   *  {status: 'error'} 表示不存在 id 的这行数据
   */
  set(id, data) {
    const table = getTable();
    const findIndex = table.findIndex((d) => d?.id == id);
    let successData = null,
      errorData = null;
    if (findIndex >= 0) {
      data = {
        ...data,
        id: table[findIndex]?.id,
      };
      table.splice(findIndex, 1, data);
      setTable(table);
      successData = { status: "success" };
    } else {
      errorData = { status: "error", message: `table中不存在该ID：${id}` };
    }
    return mockPromiseRes(successData, errorData);
  },

  /**
   * 通过 id 删除 table 中已存在的某行数据
   * @param {String} id
   *
   * @return {Boolean} {status: 'success'} 为删除成功，
   *  {status: 'error'} 为删除失败
   */
  delete(id) {
    const table = getTable();
    const findIndex = table.findIndex((d) => d?.id == id);
    let successData = null,
      errorData = null;
    if (findIndex >= 0) {
      table.splice(findIndex, 1);
      setTable(table);
      successData = { status: "success" };
    } else {
      errorData = { status: "error", message: `table中不存在该ID：${id}` };
    }
    return mockPromiseRes(successData, errorData);
  },

  /**
   * 向 table 的末尾添加一行数据
   * @param {Object} data
   *
   * @return {Boolean} {status: 'success'} 为添加成功，
   *  {status: 'error'} 为添加失败
   */
  append(data) {
    const table = getTable();
    table.push({
      ...data,
      id: randomId(),
    });
    setTable(table);
    return mockPromiseRes({ status: "success" });
  },
};

export default ajax;

const hash = "__dont_touch_me__";

// 为 每行数据，增加 id
// @TODO ID偶尔可能重复
function randomId() {
  return Math.random().toString();
}

function getTable() {
  return JSON.parse(localStorage.getItem(hash));
}

function setTable(data) {
  data.forEach((d) => {
    // 为 每行数据，增加 id
    // @TODO ID偶尔可能重复
    if (!d.id) {
      d.id = randomId();
    }
  });

  localStorage.setItem(hash, JSON.stringify(data));
}

// 模拟网络请求：
//  promise 的1S后，将数据返回
function mockPromiseRes(successData) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const randomNum = Math.random();
      if (randomNum > 0.1) {
        resolve(successData);
      } else {
        // 10% 的概率，接口报错
        reject({ status: "error", message: "接口报错" });
      }
    }, 1000);
  });
}
